package com.anyi.controller;


import cn.hutool.core.lang.Assert;
import com.anyi.common.lang.Result;
import com.anyi.entity.Article;
import com.anyi.service.ArticleService;
import com.anyi.util.MyUtils;
import com.anyi.util.RedisUtil;
import com.anyi.util.ShiroUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.http.HttpRequest;
import org.springframework.util.ClassUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author anyi
 * @since 2022-04-14
 */
@RestController
@RequestMapping("/articles")
public class ArticleController {
    @Autowired
    private ArticleService articleService;
    @Autowired
    RedisUtil redisUtil;

    @GetMapping("/test")
    public Result test(){
        return Result.success(null);
    }
    /**
     * 获取所有的文章
     * @param pageNo
     * @param limit
     * @return
     */
    @GetMapping
    public Result articles(@RequestParam(defaultValue = "1") Integer pageNo, @RequestParam(defaultValue = "4") Integer limit){
        PageHelper.startPage(pageNo,limit);
        List<Article> list = articleService.list(new QueryWrapper<Article>().orderByDesc("create_date"));
        Set<ZSetOperations.TypedTuple<String>> viewCounts = redisUtil.zReverseRangeWithScores("viewCounts", 0, 10);
        Set<ZSetOperations.TypedTuple<String>> likeCounts = redisUtil.zReverseRangeWithScores("likeCounts", 0, 10);
        PageInfo<Article> pageInfo = new PageInfo<>(list);
        List<Article> articles = MyUtils.tranFormView(viewCounts,pageInfo.getList(),"viewCounts");
        List<Article> finalArticles = MyUtils.tranFormView(likeCounts, articles,"likeCounts");
        pageInfo.setList(finalArticles);
        return Result.success(pageInfo);
    }

    /**
     * 获取最热的文章
     * @return
     */
    @GetMapping("/hot")
    public Result getHot(){
        PageHelper.startPage(1,3);
        List<Article> categoryList = articleService.list(new QueryWrapper<Article>().orderByDesc("view_counts"));
        PageInfo<Article> pageInfo = new PageInfo<>(categoryList);
        Set<ZSetOperations.TypedTuple<String>> viewCounts = redisUtil.zReverseRangeWithScores("viewCounts", 0, 10);
        Set<ZSetOperations.TypedTuple<String>> likeCounts = redisUtil.zReverseRangeWithScores("likeCounts", 0, 10);
        List<Article> articles = MyUtils.tranFormView(viewCounts,pageInfo.getList(),"viewCounts");
        List<Article> finalArticles = MyUtils.tranFormView(likeCounts, articles,"likeCounts");
        pageInfo.setList(finalArticles);
        return Result.success(pageInfo);
    }

    /**
     * 根据分类获取id
     * @param id
     * @return
     */
    @GetMapping("/category/{id}")
    public Result getCategory(@PathVariable("id")Integer id){
        List<Article> categoryList = articleService.list(new QueryWrapper<Article>().eq("category_id", id).orderByDesc("view_counts"));
        return Result.success(categoryList);
    }
    /**
     * 根据 id 获取文章`
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public Result blog(@PathVariable("id")Integer id){
        Article article = articleService.getOne(new QueryWrapper<Article>().eq("id", id));
        if(article!=null){
            redisUtil.zIncrementScore("viewCounts",id.toString(),1);
        }
        Set<ZSetOperations.TypedTuple<String>> viewCounts = redisUtil.zReverseRangeWithScores("viewCounts", 0, 10);
        Set<ZSetOperations.TypedTuple<String>> likeCounts = redisUtil.zReverseRangeWithScores("likeCounts", 0, 10);
        Article articles = MyUtils.tranFormOneView(viewCounts, article,"viewCounts");
        Article finalArticle = MyUtils.tranFormOneView(likeCounts, articles,"likeCounts");
        return Result.success(finalArticle);
    }

    /**
     * 编辑
     * @param article
     * @return
     */
    @RequiresAuthentication
    @PostMapping("/updateOrPublish")
    public Result edit(@Validated @RequestBody Article article){
        Article temp = null;
        if (article.getId() !=null){
            // 如果不等于空，就证明是编辑
            temp = articleService.getById(article.getId());
            Assert.isTrue(temp.getAuthorId().longValue() == ShiroUtil.getProfile().getId().longValue(),"没有权限编辑");
        }else {
            // 如果id等于空就是添加
            temp = new Article();
            temp.setAuthorId(ShiroUtil.getProfile().getId());
            temp.setCreateDate(LocalDateTime.now());
            temp.setLikeCounts(0);
            temp.setViewCounts(0);
        }
        BeanUtils.copyProperties(article,temp,"id","authorId","createDate","likeCounts","viewCounts");
        articleService.saveOrUpdate(temp);
        if(article.getId() == null){
            redisUtil.zAdd("viewCounts", temp.getId().toString(), temp.getViewCounts());
            redisUtil.zAdd("likeCounts", temp.getId().toString(), temp.getLikeCounts());
        }
        return Result.success(temp);
    }
    /**
     * 删除文章
     * @param id
     * @return
     */
    @RequiresAuthentication
    @GetMapping("/delete/{id}")
    public Result deleteBlog(@PathVariable("id")Integer id){
        Article article = articleService.getOne(new QueryWrapper<Article>().eq("id", id));
        if(article != null){
            redisUtil.zRemove("viewCounts",id.toString());
            redisUtil.zRemove("likeCounts",id.toString());
            articleService.removeById(id);
        }
        return Result.success(null);
    }

    @PostMapping("/upload/image")
    public Result postImage(@RequestParam("file") MultipartFile file) throws FileNotFoundException {
        File path = new File(ResourceUtils.getURL("classpath:").getPath());
        if(!path.exists()) path = new File("");

        //如果上传目录为/static/images/upload/，则可以如下获取：
        File upload = new File(path.getAbsolutePath(),"nginx/html/images/");
        if(!upload.exists()) upload.mkdirs();
        System.out.println(upload.getAbsolutePath());
        String name = file.getOriginalFilename();
        String suffixName = name.substring(name.lastIndexOf("."));

        String fileName = UUID.randomUUID().toString().replaceAll("-","") + suffixName;

        String finalFile = upload.getAbsolutePath()+"\\" + fileName;

        try {
            file.transferTo(new File(finalFile));
        } catch (Exception e) {
            return Result.fail("上传失败");
        }
        return Result.success(finalFile);
    }

    /**
     * 增加点赞
     * @return
     */
    @GetMapping("/likeAdd/{id}")
    public Result addLike(@PathVariable("id") Integer id){
        redisUtil.zIncrementScore("likeCounts",id.toString(),1);
        return Result.success(null);
    }
    @GetMapping("/likeSub/{id}")
    public Result subLike(@PathVariable("id")Integer id){
        redisUtil.zIncrementScore("likeCounts",id.toString(),-1);
        return Result.success(null);
    }
}
